﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.Text;

using Microsoft.Practices.EnterpriseLibrary.Common;
using Microsoft.Practices.EnterpriseLibrary.Validation;

namespace Arquitetura.Architectural.Model
{
    [DataContract]
    public class ResultMessage
    {
        #region Propriedade(s)
        [DataMember]
        public string EntityName
        { get; set; }

        [DataMember]
        public string EntityField
        { get; set; }

        [DataMember]
        public List<string> Informations
        { get; set; }

        [DataMember]
        public object Tag
        { get; set; }
        #endregion Propriedade(s)

        #region Construtor(es)
        public ResultMessage()
        {
            Informations = new List<string>();
        }

        public ResultMessage(ValidationResult validationResult)
            : this()
        {
            if (validationResult == null)
            {
                throw new ArgumentException("O parâmetro validationResult do tipo ValidationResult não pode ser uma referência nula.");
            }

            EntityName = validationResult.Target.GetType().Name;
            EntityField = validationResult.Key;
            Tag = validationResult.Tag;
            Informations.Add(validationResult.Message);
        }

        public ResultMessage(Exception exception)
            : this()
        {
            AddExceptionMessage(exception);
        }
        #endregion Construtor(es)

        #region Método(s)
        public void AddExceptionMessage(Exception exception)
        {
            if (exception == null)
            {
                throw new ArgumentException("O parâmetro exception do tipo Exception não pode ser uma referência nula.");
            }

            Informations.Add(exception.Message);
            if (exception.InnerException != null)
            {
                AddExceptionMessage(exception.InnerException);
            }
        }

        public string ConsolidateInformations()
        {
            return ConsolidateInformations("\n");
        }

        public string ConsolidateInformations(string separator)
        {
            return ConsolidateInformations(separator, new StringBuilder()).ToString();
        }

        public StringBuilder ConsolidateInformations(string separator, StringBuilder stringBuilder)
        {
            if (String.IsNullOrEmpty(separator))
            {
                if (separator == null)
                {
                    throw new ArgumentNullException("separator", "O parâmetro separator do tipo String não pode ser uma referência nula.");
                }
                else
                {
                    throw new ArgumentException("separator", "O parâmetro separator do tipo String não pode ser uma string vazia.");
                }
            }

            if (stringBuilder == null)
            {
                throw new ArgumentException("stringBuilder", "O parâmetro stringBuilder do tipo StringBuilder não pode ser uma referência nula.");
            }

            String lastInformacao = Informations.Last();

            foreach (String information in Informations)
            {
                if (!string.IsNullOrEmpty(information))
                {
                    stringBuilder.Append(information);
                    if (!((Object)information).Equals((Object)lastInformacao))
                    {
                        stringBuilder.Append(separator);
                    }
                }
            }
            return stringBuilder;
        }
        #endregion Método(s)
    }
}
